﻿// Doc-Encode UTF8-BOM, Space(4), Unix(LF)
#include "man_appex/appex_nser.h"
#include "klbmem/klb_mem.h"


namespace pfw {
//////////////////////////////////////////////////////////////////////////
// app extension manage net serve

#define APPEX_NSER_HANDLE       "APPEX_NSER_HANDLE*"    ///< Lua meta标示


typedef struct meta_nser_t_
{
    appex_nser_t*               p_appex;                ///< app extension
    man_nser_t*                 p_man;                  ///< 管理模块
}meta_nser_t;


///////////////////////////////////

static meta_nser_t* new_meta_nser(lua_State* L)
{
    meta_nser_t* p_meta = (meta_nser_t*)lua_newuserdata(L, sizeof(meta_nser_t));
    KLB_MEMSET(p_meta, 0, sizeof(meta_nser_t));
    luaL_setmetatable(L, APPEX_NSER_HANDLE);

    return p_meta;
}

static meta_nser_t* to_meta_nser(lua_State* L, int index)
{
    meta_nser_t* p_meta = (meta_nser_t*)luaL_checkudata(L, index, APPEX_NSER_HANDLE);
    luaL_argcheck(L, NULL != p_meta, index, "'nser' expected");
    return p_meta;
}

static int meta_nser_gc(lua_State* L)
{
    meta_nser_t* p_meta = to_meta_nser(L, 1);

    return 0;
}

static int meta_nser_tostring(lua_State* L)
{
    meta_nser_t* p_meta = to_meta_nser(L, 1);

    lua_pushfstring(L, "nser:%p", p_meta);
    return 1;
}

///////////////////////////////////

static int meta_nser_init(lua_State* L)
{
    meta_nser_t* p_meta = to_meta_nser(L, 1);       ///< @1 自身self

    int ret = man_nser_init(p_meta->p_man);

    lua_pushinteger(L, ret);                        ///< #1. 0.成功; 非0.失败(错误码)
    return 1;
}

static int meta_nser_quit(lua_State* L)
{
    meta_nser_t* p_meta = to_meta_nser(L, 1);

    man_nser_quit(p_meta->p_man);

    return 0;
}

static int meta_nser_start(lua_State* L)
{
    meta_nser_t* p_meta = to_meta_nser(L, 1);       ///< @1 自身self

    int ret = man_nser_start(p_meta->p_man);

    lua_pushinteger(L, ret);                        ///< #1. 0.成功; 非0.失败(错误码)
    return 1;
}

static int meta_nser_stop(lua_State* L)
{
    meta_nser_t* p_meta = to_meta_nser(L, 1);       ///< @1 自身self

    man_nser_stop(p_meta->p_man);

    return 0;
}

static int meta_nser_listen(lua_State* L)
{
    meta_nser_t* p_meta = to_meta_nser(L, 1);       ///< @1 自身self
    const char* p_key = luaL_checkstring(L, 2);     ///< @2 key: eg. "80"
    int port = (int)luaL_checkinteger(L, 3);        ///< @3 端口: eg. 80

    int ret = man_nser_listen(p_meta->p_man, p_key, port);

    lua_pushinteger(L, ret);                        ///< #1. 0.成功; 非0.失败(错误码)
    return 1;
}

static int meta_nser_stop_listen(lua_State* L)
{
    meta_nser_t* p_meta = to_meta_nser(L, 1);       ///< @1 自身self
    const char* p_key = luaL_checkstring(L, 2);     ///< @2 key: eg. "80"

    int ret = man_nser_stop_listen(p_meta->p_man, p_key);

    lua_pushinteger(L, ret);                        ///< #1. 0.成功; 非0.失败(错误码)
    return 1;
}

///////////////////////////////////
// meta nser 接口

static void appex_nser_createmeta(lua_State* L)
{
    static luaL_Reg meth[] = {
        { "close",              meta_nser_gc },             // 关闭 meta(句柄)

        { "init",               meta_nser_init },           // 模块初始化
        { "quit",               meta_nser_quit },           // 模块退出

        { "start",              meta_nser_start },          // 模块开始(线程)
        { "stop",               meta_nser_stop },           // 模块停止(线程)

        { "listen",             meta_nser_listen },         // 开始监听
        { "stop_listen",        meta_nser_stop_listen },    // 停止监听

        { NULL,                 NULL }
    };

    static const luaL_Reg metameth[] = {
        { "__index",            NULL },  /* place holder */
        { "__gc",               meta_nser_gc },
        { "__close",            meta_nser_gc },
        { "__tostring",         meta_nser_tostring },
        { NULL,                 NULL }
    };

    luaL_newmetatable(L, APPEX_NSER_HANDLE);/* metatable for APPEX_NSER_HANDLE handles */
    luaL_setfuncs(L, metameth, 0);          /* add metamethods to new metatable */
    luaL_newlibtable(L, meth);              /* create method table */
    luaL_setfuncs(L, meth, 0);              /* add file methods to method table */
    lua_setfield(L, -2, "__index");         /* metatable.__index = method table */
    lua_pop(L, 1);                          /* pop metatable */
}

//////////////////////////////////////////////////////////////////////////


static int appex_nser_open(lua_State* L)
{
    appex_nser_t* p_appex = appex_get_nser2();
    man_nser_t* p_man = appex_nser_get_manage(p_appex);

    // !!!注意: manage 模块是唯一的, 在Lua层 许可打开多个 meta(句柄)
    // 也可能存在 多个线程 多个 meta(句柄), 操作 manage 模块 的情况

    // 创建 meta
    meta_nser_t* p_meta = new_meta_nser(L);
    
    // 初始化 参数
    p_meta->p_appex = p_appex;
    p_meta->p_man = p_man;

    return 1;
}

//////////////////////////////////////////////////////////////////////////

// 
int appex_luaopen_nser(lua_State* L)
{
    static luaL_Reg lib[] =
    {
        { "open",               appex_nser_open },  // 打开 meta(句柄)


        { NULL,                 NULL }
    };

    // 创建导出库函数
    luaL_newlib(L, lib);

    // APPEX_NSER_HANDLE
    appex_nser_createmeta(L);

    return 1; // 表示返回 1个 table
}

//////////////////////////////////////////////////////////////////////////
} // namespace pfw

//end
